import { snippetCompletion } from '@codemirror/autocomplete';
import { localCache } from '@/utils/cache';
import cacheKey from '@/config/cacheKey';

/**
 * 公共提示代码
 */
const publicCode = [
  snippetCompletion('@get{${}}', { label: '@get{}', type: 'string', info: '获取put数据' }),
  snippetCompletion('@{${}}', { label: '@{}', type: 'string', info: '获取内置参数' }),
  { label: 'config.host', type: 'property', info: '站点地址', detail: 'config.host' },
  { label: 'config.keyword', type: 'property', info: '请求关键字' },
  { label: 'config.url', type: 'property', info: '搜索地址' },
  { label: 'config.bookUrl', type: 'property', info: '书本地址' },
  { label: 'config.bookName', type: 'property', info: '书本名称' },
  { label: 'config.chapterUrl', type: 'property', info: '章节地址' },
  { label: 'config.chapterName', type: 'property', info: '章节名称' },
  { label: 'config.pageIndex', type: 'property', info: '页面序号' },
  { label: 'config.pageStart', type: 'property', info: '页面规则起始数' },

  // 自定义的方法
  snippetCompletion(`app.doc($\{html}, \${clean})`, { label: 'app.doc()', type: 'function', detail: 'html解析' }),
  snippetCompletion('app.log(${})', { label: 'app.log()', type: 'builtin', detail: '等同于console.log' }),
  snippetCompletion('app.toast(${text}, ${type})', { label: 'app.toast()', type: 'function', detail: 'Toast' }),
  snippetCompletion(
    `app.showDialog({\n\ttitle: '\${1:提示}',\n\tbody: '\${2:提示信息}'\n},(bool) => {\n});`,
    {
      label: 'app.showDialog',
      detail: '打开一个对话框',
      type: 'function',
    }
  ),
  snippetCompletion('app.isJson(${string})', { label: 'app.isJson()', type: 'function', detail: '判断是否为json字符串' }),
  snippetCompletion(`app.time(\${unix}, \${'yyyy-MM-dd HH:mm:ss'})`, { label: 'app.time()', type: 'function', detail: '将一个UNIX时间戳转换为日期格式' }),
  snippetCompletion('app.jsonToString(${jsonObj})', { label: 'app.jsonToString()', type: 'function', detail: '将json转成字符串' }),
  snippetCompletion('app.stringToJson(${jsonString})', { label: 'app.stringToJson()', type: 'function', detail: '将字符串转成json' }),
  snippetCompletion('app.strToBytes(${string})', { label: 'app.strToBytes()', type: 'function', detail: '将字符串转化成字节序列' }),
  snippetCompletion('app.bytesToStr(${bytes})', { label: 'app.bytesToStr()', type: 'function', detail: '将字节序列转化成字符串' }),

  snippetCompletion(
    `app.post({\n\turl: \${1:"url"},\n\tparams: \${2:{}},\n\theader: \${3:{}},\n\ttimeout: \${4:60}\n});`,
    {
      label: 'app.post',
      detail: 'HTTP POST 方法模板',
      type: 'function',
    }
  ),
  snippetCompletion(
    `app.get({\n\turl: \${1:"url"},\n\tparams: \${2:{}},\n\theader: \${3:{}},\n\ttimeout: \${4:60}\n});`,
    {
      label: 'app.get',
      detail: 'HTTP GET 方法模板',
      type: 'function',
    }
  ),
  snippetCompletion(`app.sp.put($\{key}, $\{value})`, { label: 'app.sp.put()', type: 'function', detail: '持久化数据' }),
  snippetCompletion(`app.sp.get($\{key})`, { label: 'app.sp.get()', type: 'function', detail: '获取本地持久化的数据' }),
  snippetCompletion(`app.sp.delete($\{key})`, { label: 'app.sp.delete()', type: 'function', detail: '删除一个本地持久化的数据' }),
  snippetCompletion(`app.md5($\{data})`, { label: 'app.md5()', type: 'function', detail: 'MD5加密' }),
  snippetCompletion(`app.aes.encrypt($\{data}, $\{key}, $\{iv})`, { label: 'app.aes.encrypt()', type: 'function', detail: 'AES加密' }),
  snippetCompletion(`app.aes.decrypt($\{encryptData}, $\{key}, $\{iv})`, { label: 'app.aes.decrypt()', type: 'function', detail: 'AES解密' }),
  snippetCompletion(`app.rsa.encrypt($\{data}, $\{publicKey})`, { label: 'app.rsa.encrypt()', type: 'function', detail: 'RSA加密' }),
  snippetCompletion(`app.rsa.decrypt($\{encryptData}, $\{privateKey})`, { label: 'app.rsa.decrypt()', type: 'function', detail: 'RSA解密' }),
  snippetCompletion(`app.base64.encode($\{data})`, { label: 'app.base64.encode()', type: 'function', detail: 'Base64编码' }),
  snippetCompletion(`app.base64.decode($\{data})`, { label: 'app.base64.decode()', type: 'function', detail: 'Base64解码' }),
  snippetCompletion(`app.base64.decodeToBytes($\{data})`, { label: 'app.base64.decodeToBytes()', type: 'function', detail: 'Base64解码为Bytes' }),

  snippetCompletion(`app.nlp.cht($\{data})`, { label: 'app.nlp.cht()', type: 'function', detail: '简体字转繁体字' }),
  snippetCompletion(`app.nlp.chs($\{data})`, { label: 'app.nlp.chs()', type: 'function', detail: '繁体字转简体字' }),
];

/**
 * js自定义提示
 *
 * @param context
 */
export function jsAutoCode(context: any) {
  let word = context.matchBefore(/[@\w+.]*/);
  if (word.from == word.to && !context.explicit) return null;
  let codes = localCache.getCache(`${cacheKey.AUTO_CODE}_javascript`);
  if (!codes) {
    codes = [];
  }
  return {
    from: word.from,
    options: [
      // 字符串方法
      snippetCompletion('console.log(${})', { label: 'console.log()', type: 'builtin', detail: 'console.log' }),
      snippetCompletion('charAt(${index})', { label: 'charAt()', type: 'function' }),
      snippetCompletion('concat(${string1}, ${string2})', { label: 'concat()', type: 'function' }),
      snippetCompletion('indexOf(${searchValue}, ${fromIndex})', { label: 'indexOf()', type: 'function' }),
      snippetCompletion('lastIndexOf(${searchValue}, ${fromIndex})', { label: 'lastIndexOf()', type: 'function' }),
      snippetCompletion('match(${regexp})', { label: 'match()', type: 'function' }),
      snippetCompletion('replace(${searchValue}, ${replaceValue})', { label: 'replace()', type: 'function' }),
      snippetCompletion('replaceAll(${searchValue}, ${replaceValue})', { label: 'replaceAll()', type: 'function' }),
      snippetCompletion('search(${regexp})', { label: 'search()', type: 'function' }),
      snippetCompletion('slice(${startIndex}, ${endIndex})', { label: 'slice()', type: 'function' }),
      snippetCompletion('split(${separator}, ${limit})', { label: 'split()', type: 'function' }),
      snippetCompletion('substr(${startIndex}, ${length})', { label: 'substr()', type: 'function' }),
      snippetCompletion('substring(${startIndex}, ${endIndex})', { label: 'substring()', type: 'function' }),
      { label: 'toLowerCase()', type: 'function' },
      { label: 'toUpperCase()', type: 'function' },
      { label: 'trim()', type: 'function' },

      // 数组方法
      snippetCompletion('concat(${array1}, ${array2})', { label: 'concat()', type: 'function' }),
      snippetCompletion('join(${separator})', { label: 'join()', type: 'function' }),
      { label: 'pop()', type: 'function' },
      snippetCompletion('push(${element1}, ${element2})', { label: 'push()', type: 'function' }),
      { label: 'reverse()', type: 'function' },
      { label: 'shift()', type: 'function' },
      snippetCompletion('slice(${startIndex}, ${endIndex})', { label: 'slice()', type: 'function' }),
      snippetCompletion('sort(${sortFunction})', { label: 'sort()', type: 'function' }),
      snippetCompletion('splice(${startIndex}, ${deleteCount}, ${element1}, ${element2})', {
        label: 'splice()',
        type: 'function'
      }),
      { label: 'toString()', type: 'function' },
      snippetCompletion('unshift(${element1}, ${element2})', { label: 'unshift()', type: 'function' }),
      snippetCompletion('every(${callback})', { label: 'every()', type: 'function' }),
      snippetCompletion('filter(${callback})', { label: 'filter()', type: 'function' }),
      snippetCompletion('forEach(${callback})', { label: 'forEach()', type: 'function' }),
      snippetCompletion('map(${callback})', { label: 'map()', type: 'function' }),
      snippetCompletion('reduce(${callback}, ${initialValue})', { label: 'reduce()', type: 'function' }),
      snippetCompletion('some(${callback})', { label: 'some()', type: 'function' }),
      snippetCompletion('includes(${element})', { label: 'includes()', type: 'function' }),

      // 数学方法
      snippetCompletion('abs(${number})', { label: 'abs()', type: 'function' }),
      snippetCompletion('ceil(${number})', { label: 'ceil()', type: 'function' }),
      snippetCompletion('floor(${number})', { label: 'floor()', type: 'function' }),
      snippetCompletion('round(${number})', { label: 'round()', type: 'function' }),
      snippetCompletion('max(${number1}, ${number2})', { label: 'max()', type: 'function' }),
      snippetCompletion('min(${number1}, ${number2})', { label: 'min()', type: 'function' }),
      snippetCompletion('pow(${base}, ${exponent})', { label: 'pow()', type: 'function' }),
      snippetCompletion('sqrt(${number})', { label: 'sqrt()', type: 'function' }),
      { label: 'random()', type: 'function' },
      snippetCompletion('trunc(${number})', { label: 'trunc()', type: 'function' }),

      // 正则表达式
      snippetCompletion('exec(${string})', { label: 'exec()', type: 'function' }),
      snippetCompletion('test(${string})', { label: 'test()', type: 'function' }),
      snippetCompletion('compile(${pattern})', { label: 'compile()', type: 'function' }),

      // 其他方法
      snippetCompletion('eval(${string})', { label: 'eval()', type: 'function' }),
      snippetCompletion('isFinite(${number})', { label: 'isFinite()', type: 'function' }),
      snippetCompletion('isNaN(${number})', { label: 'isNaN()', type: 'function' }),
      snippetCompletion('parseFloat(${string})', { label: 'parseFloat()', type: 'function' }),
      snippetCompletion('parseInt(${string)', { label: 'parseInt()', type: 'function' }),
      snippetCompletion('encodeURI(${uri})', { label: 'encodeURI()', type: 'function' }),
      snippetCompletion('encodeURIComponent(${uri})', { label: 'encodeURIComponent()', type: 'function' }),
      snippetCompletion('decodeURI(${uri})', { label: 'decodeURI()', type: 'function' }),
      snippetCompletion('decodeURIComponent(${uri})', { label: 'decodeURIComponent()', type: 'function' }),
      snippetCompletion('escape(${string})', { label: 'escape()', type: 'function' }),
      snippetCompletion('unescape(${string})', { label: 'unescape()', type: 'function' }),
      snippetCompletion('setTimeout(${callback}, ${delay})', { label: 'setTimeout()', type: 'function' }),
      snippetCompletion('setInterval(${callback}, ${delay})', { label: 'setInterval()', type: 'function' }),
      snippetCompletion('clearInterval(${intervalId})', { label: 'clearInterval()', type: 'function' }),
      snippetCompletion('clearTimeout(${timeoutId})', { label: 'clearTimeout()', type: 'function' }),
      snippetCompletion('JSON.stringify(${object})', { label: 'JSON.stringify()', type: 'function' }),
      snippetCompletion('JSON.parse(${string})', { label: 'JSON.parse()', type: 'function' }),


      // 公共
      ...publicCode,
      ...codes
    ]
  };
}

/**
 * 字符串自定义提示
 *
 * @param context
 */
export function stringAutoCode(context: any) {
  let word = context.matchBefore(/[@\w+.]*/);
  if (word.from == word.to && !context.explicit) return null;
  let codes = localCache.getCache(`${cacheKey.AUTO_CODE}_string`);
  if (!codes) {
    codes = [];
  }
  return {
    from: word.from,
    options: [
      ...publicCode,
      snippetCompletion('<js>${}</js>', { label: '<js></js>', type: 'string', info: 'js类型标签' }),
      { label: '@js:', type: 'string', info: 'js类型头' }
    ]
  };
}
